package cn.mw.cmdb.processor;

import cn.mw.cmdb.config.CustomizeThreadPool;
import cn.mw.cmdb.entity.AssetsInterfaceDTO;
import cn.mw.cmdb.entity.AssetsInterfaceHis;
import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.entity.ItemGetDTO;
import cn.mw.cmdb.enums.InterfaceInfoEnum;
import cn.mw.cmdb.mongoMapper.AssetsInterfaceMapper;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.service.impl.AssetsManageServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.service.impl.MwInstanceMonitorManage;
import cn.mw.cmdb.template.param.ZabbixHandlerParam;
import cn.mw.cmdb.template.service.MwZabbixHandlerService;
import cn.mw.cmdb.util.CMDBScanEngineTool;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.util.SnmpSearchContext;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.api.cmdb.QueryAssetsInterfaceParam;
import cn.mw.microMonitorCommon.api.common.MwEngineManageService;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import cn.mw.microMonitorCommon.security.utils.SecurityUtils;
import cn.mw.microMonitorCommon.util.SpringUtils;
import cn.mw.scanengine.service.ScanEngineService;
import cn.mw.scanengine.service.SnmpScanService;
import cn.mw.scanengine.snmp.param.SearchParam;
import cn.mw.scanengine.snmp.scan.model.IfMode;
import cn.mw.scanengine.snmp.scan.model.IfStatus;
import cn.mw.scanengine.snmp.scan.model.VlanType;
import cn.mw.scanengine.view.DeviceInfoView;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.javers.core.Javers;
import org.javers.core.diff.Diff;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.Pair;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.mw.cmdb.enums.MonitorMethodEnum.getItemResultByApplicationName;
import static cn.mw.cmdb.processor.zabbix.ZabbixMonitorProcessor.INTERFACES;
import static cn.mw.cmdb.service.impl.AssetsManageServiceImpl.INTERFACE_NAME_VLAN_KEY;
import static cn.mw.cmdb.service.impl.AssetsManageServiceImpl.getShortName;
import static cn.mw.cmdb.util.ValConvertUtil.*;

@Component
@Slf4j
public class BusinessProcessNetwork {

    private ScanEngineService scanEngineService;
    @DubboReference(check = false, mock = "true", timeout = 15000)
    private MwEngineManageService mwEngineManageService;
    @DubboReference(check = false, timeout = 120000)
    private ZabbixDubboService zabbixDubboService;

    private VlanType vlanType;

    @Value("${cmdb.scan.debug}")
    private boolean debug;

    @Value("${cmdb.monitorHostList.insBatchFetchNum}")
    private int insBatchFetchNum;
    @Autowired
    private MwZabbixHandlerService mwZabbixHandlerService;
    private AssetsInterfaceMapper assetsInterfaceMapper;

    private Javers javers;

    public BusinessProcessNetwork(ScanEngineService scanEngineService, VlanType vlanType, AssetsInterfaceMapper assetsInterfaceMapper
            , MwEngineManageService mwEngineManageService, ZabbixDubboService zabbixDubboService, Javers javers) {
        this.scanEngineService = scanEngineService;
        this.vlanType = vlanType;
        this.assetsInterfaceMapper = assetsInterfaceMapper;
        this.mwEngineManageService = mwEngineManageService;
        this.zabbixDubboService = zabbixDubboService;
        this.javers = javers;
    }

    public void refreshIfInfo(List<InstanceInfo> instanceInfos) throws Exception {
        doAddInterfaceInfo(instanceInfos, new BeforeAddInterfaceInfo() {
            @Override
            public List<AssetsInterfaceDTO> distinct(List<AssetsInterfaceDTO> oldAssetsInterfaceDTOs) {
                if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(oldAssetsInterfaceDTOs)) {
                    List<AssetsInterfaceDTO> collect = oldAssetsInterfaceDTOs.stream().filter(s -> s.getEditorFlag() != null && s.getEditorFlag()).collect(Collectors.toList());
                    return collect;
                }
                return null;
            }

            @Override
            public void invoke(List<AssetsInterfaceDTO> assetsInterfaceDTOS, List<String> instanceIds) throws Exception {
                Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).in(instanceIds));
                query.addCriteria(CriteriaWrapper.where(AssetsInterfaceDTO::getEditorFlag).ne(true));
                assetsInterfaceMapper.remove(query);
                log.info("finish remove {}", instanceIds);
            }


        });

    }


    public void recoverCustomConfig(String instanceId, Map<Integer, AssetsInterfaceDTO> ifIndexId2AssetsInterface) throws Exception {
        List<Pair<Query, Update>> updateList = new ArrayList<>();
        for (Map.Entry<Integer, AssetsInterfaceDTO> entry : ifIndexId2AssetsInterface.entrySet()) {
            Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(instanceId).andOperator(
                    CriteriaWrapper.where(AssetsInterfaceDTO::getIfIndex).is(entry.getKey())
            ));
            Update update = CMDBTool.genMongoUpdate(entry.getValue(), null, null);
            // 更新数据
            Pair<Query, Update> updatePair = Pair.of(query, update);
            updateList.add(updatePair);
        }
        if (!CollectionUtils.isEmpty(updateList)) {
            //UNORDERED是异步执行，有错误跳过继续执行；ORDERED时有序执行，遇到错误终止
            BulkOperations operations = assetsInterfaceMapper.bulkOps(BulkOperations.BulkMode.UNORDERED, AssetsInterfaceDTO.class);
            operations.updateMulti(updateList);
            operations.execute();
        }
    }


    @Async(CustomizeThreadPool.BusinessProcessThreadPool)
    public void processInterfaceInfo(BusinessProcessEvent event) throws Exception {
        Authentication authentication = event.getAuthentication();
        SecurityContextHolder.getContext().setAuthentication(authentication);
        try {
            Object ret = event.getRet();
            if (null != ret && ret instanceof InstanceChangeRecordDTO) {
                InstanceChangeRecordDTO instanceChangeRecordDTO = (InstanceChangeRecordDTO) ret;
                log.info("processInterfaceInfo event {}", event);
                switch (event.getAction()) {
                    case batchAdd -> addInterfaceInfo(instanceChangeRecordDTO);
                }
            }
            Object destObj = event.getDestObj();
            if (null != destObj && destObj instanceof InstanceIdsParam) {
                InstanceIdsParam param = (InstanceIdsParam) destObj;
                switch (event.getAction()) {
                    case batchRemove, remove -> doRemoveInterfaceInfo(param);
                }
            }
        } catch (Exception e) {
            log.error("processInterfaceInfo", e);
        } finally {
            SecurityContextHolder.clearContext();
        }
    }

    private void doRemoveInterfaceInfo(InstanceIdsParam param) throws Exception {
        if (null != param.getIds() && !param.getIds().isEmpty()) {
            Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).in(param.getIds()));
            assetsInterfaceMapper.remove(query);
        }
    }

    private void addInterfaceInfo(InstanceChangeRecordDTO instanceChangeRecordDTO) throws Exception {
        List<InstanceInfo> instanceInfos = instanceChangeRecordDTO.getInstanceInfos();
        doAddInterfaceInfo(instanceInfos, null);
    }

    private void doAddInterfaceInfo(List<InstanceInfo> instanceInfos, BeforeAddInterfaceInfo beforeAddInterfaceInfo) throws Exception {
        //遍历实例信息获取engineId
        if (null == instanceInfos) {
            log.info("addInterfaceInfo instanceInfos is null");
            return;
        }
        List<String> netWorkGroupIds = Arrays.asList(SpringUtils.getPropertiesValue("base.network.groupId"), SpringUtils.getPropertiesValue("base.safeEquip.groupId"));
        String serverGroupIds = SpringUtils.getPropertiesValue("base.mwServer.groupId");
        Map<String, AssetsInterfaceHis> interfaceHisMap = new HashMap<>();
        //网络设备，安全设备
        List<InstanceInfo> netWorkList = instanceInfos.stream().filter(s -> s.getPath().stream().anyMatch(netWorkGroupIds::contains)).collect(Collectors.toList());
        //服务器设备
        List<InstanceInfo> serverList = instanceInfos.stream().filter(s -> s.getPath().contains(serverGroupIds)).collect(Collectors.toList());
        List<AssetsInterfaceDTO> assetsInterfaceDTOS = new ArrayList<>();
        if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(netWorkList)) {
            getAssetInterfaceListBySNMPScan(netWorkList, assetsInterfaceDTOS, interfaceHisMap);
        }
        if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(serverList)) {
            getAssetInterfaceListByZabbix(serverList, assetsInterfaceDTOS, interfaceHisMap);
        }
        List<String> instanceIds = instanceInfos.stream().map(InstanceInfo::getId).collect(Collectors.toList());


        List<AssetsInterfaceDTO> distinctIgnoreList = new ArrayList<>();
        if (null != assetsInterfaceDTOS) {
            //比较是否有更新
            //查询接口信息
            Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).in(instanceIds));
            List<AssetsInterfaceDTO> oldAssetsInterfaceDTOs = assetsInterfaceMapper.find(query);
            Set<String> changeAssetsInterfaceInstanceIds = new HashSet<>();
            if (null != oldAssetsInterfaceDTOs) {
                Diff diff = javers.compareCollections(oldAssetsInterfaceDTOs, assetsInterfaceDTOS, AssetsInterfaceDTO.class);
                if (null != beforeAddInterfaceInfo) {
                    distinctIgnoreList = beforeAddInterfaceInfo.distinct(oldAssetsInterfaceDTOs);
                }
                if (diff.hasChanges()) {
                    log.info("AssetsInterface has change");
                    diff.getChanges().forEach(change -> {
                        Optional<Object> objectOptional = change.getAffectedObject();
                        Object obj = objectOptional.get();
                        if (obj instanceof AssetsInterfaceDTO) {
                            AssetsInterfaceDTO assetsInterfaceDTO = (AssetsInterfaceDTO) obj;
                            if (!changeAssetsInterfaceInstanceIds.contains(assetsInterfaceDTO.getInstanceId())) {
                                changeAssetsInterfaceInstanceIds.add(assetsInterfaceDTO.getInstanceId());
                            }
                        }
                    });
                }
            } else {
                log.info("oldAssetsInterfaceDTOs is null add all instanceIds");
                changeAssetsInterfaceInstanceIds.addAll(instanceIds);
            }

            if (!changeAssetsInterfaceInstanceIds.isEmpty()) {
                List<AssetsInterfaceDTO> updateAssetsInterfaceDTOs = new ArrayList<>();
                for (AssetsInterfaceDTO assetsInterfaceDTO : assetsInterfaceDTOS) {
                    if (changeAssetsInterfaceInstanceIds.contains(assetsInterfaceDTO.getInstanceId())) {
                        updateAssetsInterfaceDTOs.add(assetsInterfaceDTO);
                    }
                }
                if (null != beforeAddInterfaceInfo) {
                    beforeAddInterfaceInfo.invoke(updateAssetsInterfaceDTOs, new ArrayList<>(changeAssetsInterfaceInstanceIds));
                }

                if (!updateAssetsInterfaceDTOs.isEmpty()) {
                    Set<String> collect = null;
                    //以实例id和ifIndex唯一标识
                    if (null != distinctIgnoreList) {
                        collect = distinctIgnoreList.stream().filter(s -> s.getInstanceId() != null && s.getIfIndex() != null).map(s -> s.getInstanceId() + "_" + s.getIfIndex()).collect(Collectors.toSet());
                    }
                    BulkOperations bulkOps = assetsInterfaceMapper.bulkOps(BulkOperations.BulkMode.UNORDERED, AssetsInterfaceDTO.class);
                    for (AssetsInterfaceDTO assetsInterfaceDTO : updateAssetsInterfaceDTOs) {
                        //新增的数据中含有修改标识的数据，忽略不更新
                        if (collect != null && collect.contains(assetsInterfaceDTO.getInstanceId() + "_" + assetsInterfaceDTO.getIfIndex())) {
                            continue;
                        }
                        bulkOps.insert(assetsInterfaceDTO);
                    }
                    bulkOps.execute();

                    //先更新数据库,产生了id之后,保存变更记录
                    for (String instanceId : changeAssetsInterfaceInstanceIds) {
                        AssetsInterfaceHis assetsInterfaceHis = interfaceHisMap.get(instanceId);
                        if (null != assetsInterfaceHis) {
                            String author = SecurityUtils.getUserId().toString();
                            javers.commit(author, assetsInterfaceHis);
                        }
                    }
                } else {
                    log.info("updateAssetsInterfaceDTOs is empty");
                }

            }
            syncZabbixInterfaceMonitorInfo(beforeAddInterfaceInfo, instanceInfos, assetsInterfaceDTOS);
        } else {
            log.info("find no assetsInterfaceDTO");
        }
    }

    public void syncZabbixInterfaceMonitorInfo(BeforeAddInterfaceInfo beforeAddInterfaceInfo, List<InstanceInfo> instanceInfos, List<AssetsInterfaceDTO> assetsInterfaceDTOS) throws Exception {
        //获取交换机模型下的实例Id
        String switchModelId = SpringUtils.getPropertiesValue("base.network.switch.modelId");
        Map<String, List<AssetsInterfaceDTO>> collect = assetsInterfaceDTOS.stream().filter(s -> s.getInstanceId() != null).collect(Collectors.groupingBy(s -> s.getInstanceId()));
        //如果是资产新增，需要同步设置自动发现规则和告警标记
        if (beforeAddInterfaceInfo == null) {
            for (InstanceInfo instanceInfo : instanceInfos) {
                String hostId = instanceInfo.getMonitorTypeId();
                Integer serverId = instanceInfo.getMonitorServerId();
                String instanceId = instanceInfo.getId();
                List<String> names = new ArrayList<>();
                //是否trunk监控
                boolean trunkMonitorFlagKey = booleanValueConvert(instanceInfo.getTrunkMonitorFlagKey());
                List<String> interfaceAllNames = new ArrayList<>();
                if (collect != null && collect.containsKey(instanceId)) {
                    List<AssetsInterfaceDTO> disAssetsInterfaceDTOS = collect.get(instanceId);
                    if (!CollectionUtils.isEmpty(disAssetsInterfaceDTOS)) {
                        interfaceAllNames = disAssetsInterfaceDTOS.stream().map(s -> s.getName()).collect(Collectors.toList());
                        for (AssetsInterfaceDTO assetsInterfaceDTO : disAssetsInterfaceDTOS) {
                            //如果交换机接口,且trunk监控的
                            if (switchModelId.equals(instanceInfo.getModelId()) && trunkMonitorFlagKey) {
                                assetsInterfaceDTO.setConvertName(getShortName(assetsInterfaceDTO.getName()));
                                boolean ifModeFlag = IfMode.trunk.name().equals(assetsInterfaceDTO.getIfMode());
                                boolean interfaceNameFlag = assetsInterfaceDTO.getName().contains(INTERFACE_NAME_VLAN_KEY);
                                boolean statusFlag = IfStatus.up == assetsInterfaceDTO.getState();
                                //类型时Trunk + up的
                                //接口名称包含Vlan + up的
                                if (statusFlag && (ifModeFlag || interfaceNameFlag)) {
                                    assetsInterfaceDTO.setShowFlag(true);
                                    assetsInterfaceDTO.setAlertFlag(true);
                                    assetsInterfaceDTO.setEditorFlag(true);
                                    assetsInterfaceDTO.setItemFlag(true);
                                    names.add(assetsInterfaceDTO.getName());
                                }else{
                                    assetsInterfaceDTO.setShowFlag(false);
                                    assetsInterfaceDTO.setAlertFlag(false);
                                    assetsInterfaceDTO.setItemFlag(false);
                                }
                            } else {
                                if (IfStatus.up == assetsInterfaceDTO.getState()) {
                                    assetsInterfaceDTO.setShowFlag(true);
                                    assetsInterfaceDTO.setAlertFlag(true);
                                    assetsInterfaceDTO.setEditorFlag(true);
                                    assetsInterfaceDTO.setItemFlag(true);
                                    names.add(assetsInterfaceDTO.getName());
                                }else{
                                    assetsInterfaceDTO.setShowFlag(false);
                                    assetsInterfaceDTO.setAlertFlag(false);
                                    assetsInterfaceDTO.setItemFlag(false);
                                }
                            }
                        }
                    }

                }

                ZabbixHandlerParam zabbixHandlerParam = new ZabbixHandlerParam();
                zabbixHandlerParam.setInterfaceNames(names);
                zabbixHandlerParam.setServerId(serverId);
                zabbixHandlerParam.setHostId(hostId);
                if (!CollectionUtils.isEmpty(interfaceAllNames)) {
                    interfaceAllNames.removeAll(names);
                    zabbixHandlerParam.setDisplayInterfaceList(interfaceAllNames);
                }
                log.info("syncZabbixInterfaceMonitorInfo::" + strValueConvert(zabbixHandlerParam));
                //更新自动发现规则过滤信息(状态为显示的才生成自动发现规则)
                zabbixHandlerParam.setStatus(true);
                //开启自动发现规则
                mwZabbixHandlerService.updateDiscoveryRuleFilterInfo(zabbixHandlerParam);
                //开启告警触发器
                mwZabbixHandlerService.interfaceTriggerDeactivate(zabbixHandlerParam);
            }
            AssetsManageServiceImpl bean = SpringUtils.getBean(AssetsManageServiceImpl.class);
            //修改接口数据
            bean.batchUpdateInterfaceList(assetsInterfaceDTOS);
        }
    }


    public void getAssetInterfaceListByZabbix(List<InstanceInfo> instanceInfos, List<AssetsInterfaceDTO> assetsInterfaceDTOs, Map<String, AssetsInterfaceHis> interfaceHisMap) throws Exception {
        //zabbix获取接口数据
        List<InstanceInfo> disList = instanceInfos.stream().filter(s -> s.getMonitorServerId() != null && s.getMonitorTypeId() != null).collect(Collectors.toList());
        Map<String, String> instanceIdByHostIdMap = instanceInfos.stream().filter(s -> s.getMonitorServerId() != null && s.getMonitorTypeId() != null).collect(Collectors.toMap(s -> s.getMonitorServerId() + "_" + s.getMonitorTypeId(), s -> s.getId()));
        List<String> itemNames = Arrays.asList(
                InterfaceInfoEnum.MW_INTERFACE_SPEED.getName(),
                InterfaceInfoEnum.INTERFACE_IN_UTILIZATION.getName(),
                InterfaceInfoEnum.INTERFACE_OUT_UTILIZATION.getName(),
                InterfaceInfoEnum.INTERFACE_MTU.getName(),
                InterfaceInfoEnum.INTERFACE_MACADDR.getName(),
                InterfaceInfoEnum.INTERFACE_INDEX.getName(),
                InterfaceInfoEnum.INTERFACE_DESCR.getName(),
                InterfaceInfoEnum.MW_INTERFACE_STATUS.getName());
        Map<Integer, List> mapList = new HashMap<>();
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(disList)) {
            MwInstanceMonitorManage monitorManage = new MwInstanceMonitorManage(zabbixDubboService);
            List<QueryMonitorValue> zabbixParams = monitorManage.zabbixParamListConvert(disList);
            for (QueryMonitorValue queryMonitorValue : zabbixParams) {
                QueryMonitorParam queryMonitorParam = (QueryMonitorParam) queryMonitorValue;
                ParamContext paramContext = new ParamContext();
                List<String> hostIds = queryMonitorParam.getHostIds();
                Integer monitorServerId = queryMonitorParam.getMonitorServerId();
                List<List<String>> hostIdGroups = null;
                if (null != hostIds) {
                    hostIdGroups = Lists.partition(hostIds, insBatchFetchNum);
                }
                //需要多线程处理的集合
                paramContext.setSubList(hostIdGroups);
                paramContext.setItemNames(itemNames);
                paramContext.setApplicationName(INTERFACES);
                //调用多线程处理zabbix接口
                List<Object> objects = monitorManage.handlerSubListMethodThread(queryMonitorParam, paramContext, getItemResultByApplicationName.getName());
                mapList.put(monitorServerId, objects);
            }
            if (!CollectionUtils.isEmpty(mapList)) {
                for (Map.Entry<Integer, List> entry : mapList.entrySet()) {
                    Integer k = entry.getKey();
                    List v = entry.getValue();
                    Integer monitorServerId = k;
                    List<MWZabbixAPIResult> mwZabbixAPIResultList = (List<MWZabbixAPIResult>) v;
                    List<ItemGetDTO> itemGetDTOList = null;
                    for (MWZabbixAPIResult zabbixAPIResult : mwZabbixAPIResultList) {
                        if (zabbixAPIResult != null && zabbixAPIResult.isSuccess()) {
                            itemGetDTOList = JSONArray.parseArray(JSON.toJSONString(zabbixAPIResult.getData()), ItemGetDTO.class);
                        }
                    }
                    dataConvert(itemGetDTOList, assetsInterfaceDTOs, monitorServerId, instanceIdByHostIdMap);
                }
                if (null != assetsInterfaceDTOs) {
                    for (AssetsInterfaceDTO dto : assetsInterfaceDTOs) {
                        String instanceId = dto.getInstanceId();
                        AssetsInterfaceHis assetsInterfaceHis = interfaceHisMap.get(instanceId);
                        if (null == assetsInterfaceHis) {
                            assetsInterfaceHis = new AssetsInterfaceHis();
                            assetsInterfaceHis.setInstanceId(instanceId);
                            interfaceHisMap.put(instanceId, assetsInterfaceHis);
                        }
                        assetsInterfaceHis.addAssetsInterfaceDTO(dto);
                    }


                }
            }


        }
    }

    public void getAssetInterfaceListBySNMPScan(List<InstanceInfo> instanceInfos, List<AssetsInterfaceDTO> assetsInterfaceDTOS, Map<String, AssetsInterfaceHis> interfaceHisMap) throws Exception {
        //snmp扫描获取接口数据
        List<String> instanceIds = instanceInfos.stream().map(InstanceInfo::getId).collect(Collectors.toList());
        log.info("doAddInterfaceInfo instanceIds:{}", instanceIds);
        List<DeviceInfoView> deviceInfoViews = getInterfacedeviceInfoViews(instanceInfos);
        Map<String, String> ipInstanceIdMap = instanceInfos.stream()
                .filter(instanceInfo -> StringUtils.hasText(instanceInfo.getInBandIp()))
                .collect(Collectors.toMap(InstanceInfo::getInBandIp, InstanceInfo::getId, (existValue, newValue) -> existValue));

        Map<String, List<AssetsInterfaceDTO>> assetsInterfaceDTOMap = CMDBScanEngineTool.getIPAssetsInterfacesMap(deviceInfoViews, vlanType, debug);


        if (null != assetsInterfaceDTOMap) {
            for (Map.Entry<String, List<AssetsInterfaceDTO>> entry : assetsInterfaceDTOMap.entrySet()) {
                String instanceId = ipInstanceIdMap.get(entry.getKey());
                if (StringUtils.hasText(instanceId)) {
                    if (null == assetsInterfaceDTOS) {
                        assetsInterfaceDTOS = new ArrayList<>();
                    }
                    List<AssetsInterfaceDTO> assetsInterfaceDTOs = entry.getValue();
                    if (null != assetsInterfaceDTOs) {
                        AssetsInterfaceHis assetsInterfaceHis = interfaceHisMap.get(instanceId);
                        if (null == assetsInterfaceHis) {
                            assetsInterfaceHis = new AssetsInterfaceHis();
                            assetsInterfaceHis.setInstanceId(instanceId);
                            interfaceHisMap.put(instanceId, assetsInterfaceHis);
                        }
                        for (AssetsInterfaceDTO assetsInterfaceDTO : assetsInterfaceDTOs) {
                            assetsInterfaceDTO.setInstanceId(instanceId);
                            assetsInterfaceDTOS.add(assetsInterfaceDTO);
                            assetsInterfaceHis.addAssetsInterfaceDTO(assetsInterfaceDTO);
                        }
                    }
                }
            }
        }
    }

    public void dataConvert(List<ItemGetDTO> itemGetDTOList, List<AssetsInterfaceDTO> list, Integer monitorServerId, Map<String, String> instanceIdByHostIdMap) {
        if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(itemGetDTOList)) {
            Map<String, List<ItemGetDTO>> collect = itemGetDTOList.stream().collect(Collectors.groupingBy(ItemGetDTO::getHostid));
            for (Map.Entry<String, List<ItemGetDTO>> value : collect.entrySet()) {
                List<ItemGetDTO> dtos = value.getValue();
                String lastValueStr = null;
                AssetsInterfaceDTO interfaceDTO = new AssetsInterfaceDTO();
                for (ItemGetDTO dto : dtos) {
                    String interfaceName = dto.getOriginalType().replace("[", "").replace("]", "");
                    ;
                    interfaceDTO.setName(interfaceName);
                    String name = dto.getName();
                    String hostid = dto.getHostid();
                    String key = monitorServerId + "_" + hostid;
                    if (instanceIdByHostIdMap != null && instanceIdByHostIdMap.containsKey(key)) {
                        String instanceId = instanceIdByHostIdMap.get(key);
                        interfaceDTO.setInstanceId(instanceId);
                    }
                    if (InterfaceInfoEnum.INTERFACE_INDEX.getName().equals(name)) {
                        lastValueStr = dto.getLastvalue();
                        interfaceDTO.setIfIndex(intValueConvert(lastValueStr));
                    }
                    if (InterfaceInfoEnum.INTERFACE_MACADDR.getName().equals(name)) {
                        lastValueStr = dto.getLastvalue();
                        interfaceDTO.setMac(lastValueStr);
                    }
                    if (InterfaceInfoEnum.INTERFACE_DESCR.getName().equals(name)) {
                        lastValueStr = dto.getLastvalue();
                        interfaceDTO.setDescription(lastValueStr);
                        interfaceDTO.setAlias(lastValueStr);
                    }
                    if (InterfaceInfoEnum.MW_INTERFACE_STATUS.getName().equals(name)) {
                        lastValueStr = dto.getLastvalue();
                        IfStatus ifStatus = IfStatus.getIfStatus(intValueConvert(lastValueStr));
                        interfaceDTO.setState(ifStatus);
                    }
                }
                list.add(interfaceDTO);
            }
        }
    }


    public List<DeviceInfoView> getInterfacedeviceInfoViews(List<InstanceInfo> instanceInfos) throws Exception {
        ThreadPoolTaskExecutor executor = SpringUtils.getBean(CustomizeThreadPool.ScanThreadPool, ThreadPoolTaskExecutor.class);
        log.info("executor info ActiveCount:{},PoolSize:{},MaxPoolSize:{}", executor.getActiveCount(), executor.getPoolSize(), executor.getMaxPoolSize());
        List<DeviceInfoView> deviceInfoViews = CMDBScanEngineTool.getSnmpDeviceInfoView(scanEngineService, executor
                , instanceInfos, new Function<SnmpSearchContext<SnmpScanService>, List<DeviceInfoView>>() {
                    @Override
                    public List<DeviceInfoView> apply(SnmpSearchContext<SnmpScanService> snmpSearchContext) {
                        SnmpScanService snmpScanService = snmpSearchContext.getSnmpScanService();
                        List<SearchParam> searchParams = snmpSearchContext.getSearchParamList();
                        if (null == searchParams) {
                            return null;
                        }

                        if (null == snmpScanService) {
                            log.warn("snmpScanService is null {}", searchParams.toString());
                            return null;
                        }

                        List<DeviceInfoView> ret = null;
                        log.info("start scanInterfaceInfo {},{}", snmpSearchContext.getServiceIp(), searchParams.toString());
                        try {
                            ret = snmpScanService.scanInterfaceInfo(searchParams, false);
                        } catch (Exception e) {
                            log.error("scanInterfaceInfo", e);
                        }
                        log.info("finish scanInterfaceInfo");
                        return ret;
                    }
                }, mwEngineManageService);
        return deviceInfoViews;
    }

    public List<AssetsInterfaceDTO> listAssetsInterfaces(QueryAssetsInterfaceParam queryAssetsInterfaceParam) throws Exception {
        Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(queryAssetsInterfaceParam.getInstanceId()));
        List<AssetsInterfaceDTO> ret = assetsInterfaceMapper.find(query);
        return ret;
    }

    public List<AssetsInterfaceDTO> listAssetsInterfaces(List<String> instanceIds) throws Exception {
        Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).in(instanceIds));
        List<AssetsInterfaceDTO> ret = assetsInterfaceMapper.find(query);
        return ret;
    }
}
